%%%-------------------------------------------------------------------
%%% @author wang
%%% @copyright (C) 2018, <COMPANY>
%%% @doc
%%%
%%% @end
%%% Created : 10. 十月 2018 9:24
%%%-------------------------------------------------------------------
-module(server2).
-author("wang").

%% API
-export([start/2, rpc/2]).

start(Name, Mod) ->
  register(Name, spawn(fun() -> loop(Name, Mod, Mod:init()) end)).

rpc(Name, Request) ->
  Name ! {self(), Request},
  receive
    {Name, crash} -> exit(rpc);
    {Name, Response} -> Response
  end.

loop(Name, Mod, OldState) ->
  receive
    {From, Request} ->
      try Mod:handle(Request, OldState) of {Response, NewState} ->
        From ! {Name, Response},
        loop(Name, Mod, NewState)
      catch
        _:Why ->
          log_the_error(Name, Request, Why),
          From ! {Name, crash}, %% 发送一个消息让客户端crash
          loop(Name, Mod, OldState) %% 以初始状态继续循环
      end
  end.

log_the_error(Name, Request, Why) ->
  io:format("Server ~p request ~p ~n caused exception ~p~n", [Name, Request, Why]).
